package main

import (
	"context"
	"demo/micro/grpc/etcdclient"
	"fmt"
	"go.etcd.io/etcd/clientv3"
	"time"
)

var (
	cli *clientv3.Client
)

func Register(etcdAddr, serviceName, addr string, ttl int64) (err error) {
	serviceName = "/grpc/" + serviceName

	if cli == nil {
		cli, err = etcdclient.EtcdInit(etcdAddr)
		if err != nil {
			return err
		}
	}

	//创建租约，维持心跳
	path := serviceName + "/" + addr
	leaseID, err := CreateLease(ttl)
	if err != nil {
		return err
	}
	//存储服务注册数据
	cli.Put(context.Background(), path, addr, clientv3.WithLease(leaseID))
	fmt.Println("register service, path=" + path + ", addr=" + addr)

	//断线重连
	go CheckUnConnect(etcdAddr, serviceName, ttl)

	return nil
}

func CreateLease(ttl int64) (leaseId clientv3.LeaseID, err error) {
	//在租约内设置key
	resp, err := cli.Grant(context.Background(), ttl)
	if err != nil {
		return -1, err
	}
	_, err = cli.KeepAlive(context.Background(), resp.ID)
	if err != nil {
		return -1, err
	}

	return resp.ID, nil
}

/**
断线重连
查询etcd 服务注册数据，如果租约过期，数据被清空，则重新创建租约，建立心跳，并存储服务注册数据
*/
func CheckUnConnect(serviceName, addr string, ttl int64) {
	ticker := time.NewTicker(time.Second)

	for {
		serviceName = "/grpc/" + serviceName
		path := serviceName + "/" + addr

		resp, err := cli.Get(context.Background(), path)
		if err != nil {
			fmt.Println(err)
		}

		if resp.Count == 0 {
			leaseID, err := CreateLease(ttl)
			if err != nil {
				fmt.Println(err)
			} else {
				//存储服务注册数据
				cli.Put(context.Background(), path, addr, clientv3.WithLease(leaseID))
				fmt.Println("register service, path=" + path + ", addr=" + addr)
			}
		}

		<-ticker.C
	}

}

func UnRegister(serviceName, addr string) {
	serviceName = "/grpc/" + serviceName
	path := serviceName + "/" + addr
	if cli != nil {
		cli.Delete(context.Background(), path)
		fmt.Println("unregister, path=" + path)
	}
}
